package com.zdkj.subway.st.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.zdkj.common.core.exceltools.IExcelExport;
import com.zdkj.common.core.util.R;
import com.zdkj.common.core.util.SpringContextHolder;
import com.zdkj.common.log.annotation.SysLog;
import com.zdkj.common.security.util.ObjectUtils;
import com.zdkj.subway.st.dto.in.SwTkStockMonthCheckDTO;
import com.zdkj.subway.st.dto.out.SwTkStockMonthCheckOutDTO;
import com.zdkj.subway.st.entity.SwTkStockMonthCheck;
import com.zdkj.subway.st.entity.SwTkStockMonthCheckDetail;
import com.zdkj.subway.st.service.SwTkStockMonthCheckDetailService;
import com.zdkj.subway.st.service.SwTkStockMonthCheckService;
import com.zdkj.subway.st.util.DateUtilsSt;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.beans.BeanUtils;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;


/**
 * 车线网层级车票周期盘点主表
 *
 * @author cui_com
 * @date 2020-09-04 15:03:53
 */
@RestController
@AllArgsConstructor
@RequestMapping("/swtkstockmonthcheck")
@Api(value = "swtkstockmonthcheck", tags = "车线网层级车票周期盘点主表管理")
public class SwTkStockMonthCheckController {

    private final SwTkStockMonthCheckService swTkStockMonthCheckService;

    private final SwTkStockMonthCheckDetailService swTkStockMonthCheckDetailService;

    /**
     * 分页查询
     *
     * @param page                分页对象
     * @param swTkStockMonthCheck 车线网层级车票周期盘点主表
     * @return
     */
    @ApiOperation(value = "分页查询", notes = "分页查询")
    @GetMapping("/page")
    public R getSwTkStockMonthCheckPage(Page page, SwTkStockMonthCheck swTkStockMonthCheck) {
        return R.ok(swTkStockMonthCheckService.page(page, Wrappers.query(swTkStockMonthCheck).orderByDesc("statistical_time")));
    }


    /**
     * 分页查询明细信息
     *
     * @param page                分页对象
     * @param swTkStockMonthCheckDetail 车线网层级车票周期盘点明细表
     * @return
     */
    @ApiOperation(value = "分页查询明细信息", notes = "分页查询明细信息")
    @GetMapping("/queryDetails")
    public R getSwTkStockMonthCheckPage(Page page, SwTkStockMonthCheckDetail swTkStockMonthCheckDetail) {
        return R.ok(swTkStockMonthCheckDetailService.page(page, Wrappers.query(swTkStockMonthCheckDetail).orderByAsc("TICKET_TYPE","TICKET_TYPE_PARAM")));
    }


    /**
     * 通过id查询车线网层级车票周期盘点主表
     *
     * @param id id
     * @return R
     */
    @ApiOperation(value = "通过id查询", notes = "通过id查询")
    @GetMapping("/{id}")
    public R<SwTkStockMonthCheckOutDTO> getById(@PathVariable("id") Integer id) {
        SwTkStockMonthCheck month = swTkStockMonthCheckService.getById(id);
        SwTkStockMonthCheckOutDTO dto = new SwTkStockMonthCheckOutDTO();
        BeanUtils.copyProperties(month, dto);
        dto.setYearMonth(month.getDateYearMonth());
        /*dto.setListDetails(swTkStockMonthCheckDetailService.list(Wrappers.<SwTkStockMonthCheckDetail>query().lambda()
                .eq(SwTkStockMonthCheckDetail::getRefId, id)));*/
        return R.ok(dto);
    }

    /**
     * 生成月盘点表
     *
     * @return R
     */
    @ApiOperation(value = "生成月盘点表", notes = "生成月盘点表")
    @SysLog("生成月盘点表")
    @PostMapping
    @PreAuthorize("@pms.hasPermission('st_sw_tk_stock_month_check_add')")
    public R save() {
        //1.检查当月是否有记录，有了就干掉
        String yearMonth = DateUtilsSt.getYearMonthNowFormatter();
        SwTkStockMonthCheck monthDb = swTkStockMonthCheckService.getOne(Wrappers.<SwTkStockMonthCheck>query()
                .lambda().eq(SwTkStockMonthCheck::getDateYearMonth, yearMonth));
        if (null != monthDb) {
            swTkStockMonthCheckDetailService.remove(Wrappers.<SwTkStockMonthCheckDetail>query()
                    .lambda().eq(SwTkStockMonthCheckDetail::getRefId, monthDb.getId()));
            swTkStockMonthCheckService.removeById(monthDb.getId());
        }
        //2.从车票库存日盘点记录(sw_tk_stock_day_check_detail) 中统计,先保存主表，生成ID
        SwTkStockMonthCheck month = ObjectUtils.getDefaultObj(SwTkStockMonthCheck.class);
        month.setDateYearMonth(yearMonth);
        month.setStatisticalTime(DateUtilsSt.getDateNowFormatter());
        swTkStockMonthCheckService.save(month);

        //生成子表记录
        List<SwTkStockMonthCheckDetail> listDetail =
                swTkStockMonthCheckDetailService.queryStatisticsByYearMonth(yearMonth);
        listDetail.forEach(detail -> {
            detail.setRefId(month.getId());
            detail.setDifferenceNumber(detail.getSettleNumber());
        });

        //计算子表的结存数量,然后更新主表
        month.setSettleNumber(listDetail.stream().mapToInt(SwTkStockMonthCheckDetail::getSettleNumber).sum());
        month.setDifferenceNumber(listDetail.stream().mapToInt(SwTkStockMonthCheckDetail::getSettleNumber).sum());
        swTkStockMonthCheckService.updateById(month);

        //3.生成主表，生成子记录
        swTkStockMonthCheckDetailService.saveBatch(listDetail);
        return R.ok();
    }

    /**
     * 修改主表及明细数据
     *
     * @param swTkStockMonthCheckDTO
     * @return R
     */
    @ApiOperation(value = "修改主表及明细数据", notes = "修改主表及明细数据")
    @SysLog("修改主表及明细数据")
    @PutMapping
    @PreAuthorize("@pms.hasPermission('st_sw_tk_stock_month_check_edit')")
    public R updateById(@RequestBody SwTkStockMonthCheckDTO swTkStockMonthCheckDTO) {
        //修改没啥需要处理的，直接更新就完了
        SwTkStockMonthCheck month = new SwTkStockMonthCheck();
        BeanUtils.copyProperties(swTkStockMonthCheckDTO, month);
        List<SwTkStockMonthCheckDetail> listDetail = new ArrayList<>();
        swTkStockMonthCheckDTO.getListDetails().forEach(detail -> {
            SwTkStockMonthCheckDetail checkDetail = new SwTkStockMonthCheckDetail();
            BeanUtils.copyProperties(detail, checkDetail);
            listDetail.add(checkDetail);
        });
        if (!listDetail.isEmpty()) {
            swTkStockMonthCheckDetailService.updateBatchById(listDetail);
        }
        //求盘点数量合计值和差异数量合计值
        QueryWrapper<SwTkStockMonthCheckDetail> queryWrapper = new QueryWrapper<>();
        queryWrapper.select("ifnull(sum(check_number),0) as sumCheckNumber,ifnull(sum(difference_number),0) as sumDifferenceNumber");
        queryWrapper.lambda().eq(SwTkStockMonthCheckDetail::getRefId,month.getId());
        SwTkStockMonthCheckDetail ord= swTkStockMonthCheckDetailService.getOne(queryWrapper);
        //取值
        month.setCheckNumber(ord.getSumCheckNumber());
        month.setDifferenceNumber(ord.getSumDifferenceNumber());
        return R.ok(swTkStockMonthCheckService.updateById(month));
    }

    /**
     * 通过id删除车线网层级车票周期盘点主表
     *
     * @param id id
     * @return R
     */
    @ApiOperation(value = "通过id删除车线网层级车票周期盘点主表", notes = "通过id删除车线网层级车票周期盘点主表")
    @SysLog("通过id删除车线网层级车票周期盘点主表")
    @DeleteMapping("/{id}")
    @PreAuthorize("@pms.hasPermission('st_sw_tk_stock_month_check_del')")
    public R removeById(@PathVariable Integer id) {
        swTkStockMonthCheckDetailService.remove(Wrappers.<SwTkStockMonthCheckDetail>query()
                .lambda().eq(SwTkStockMonthCheckDetail::getRefId, id));
        return R.ok(swTkStockMonthCheckService.removeById(id));
    }

    /**
     * 导出
     *
     * @param swTkStockMonthCheck
     * @return
     * @throws IOException
     */
    @GetMapping("/export")
    @PreAuthorize("@pms.hasPermission('st_sw_tk_stock_month_check_export')")
    public R exportExcel(SwTkStockMonthCheck swTkStockMonthCheck) throws IOException {
        List<SwTkStockMonthCheck> swTkStockMonthCheckDetailList = swTkStockMonthCheckService.list(Wrappers.query(swTkStockMonthCheck));
        IExcelExport excelExport = SpringContextHolder.getBean("commonExcelExport");
        Workbook workbook = excelExport.parse(swTkStockMonthCheckDetailList);
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        workbook.write(baos);
        return R.ok(baos.toByteArray());
    }
}
